package kbpost

import (
	"context"
	"strconv"
	"strings"

	"mall/common/globalkey"
	"mall/common/jwt"
	"mall/common/resultx"
	"mall/common/utils/pointy"
	"mall/service/blog/rpc/blogclient"
	"mall/service/forum/api/internal/logic/util"
	"mall/service/forum/api/internal/svc"
	"mall/service/forum/api/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type CheckEntryFavoriteLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewCheckEntryFavoriteLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CheckEntryFavoriteLogic {
	return &CheckEntryFavoriteLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *CheckEntryFavoriteLogic) CheckEntryFavorite(
	req *types.CheckEntryFavoriteReq,
	headers *[]*types.Header,
) (*types.CheckEntryFavoriteResp, error) {
	if req.EntryId == nil || *req.EntryId == 0 {
		return nil, resultx.NewErrCode(resultx.ENTRY_ID_REQUIRED)
	}

	if req.Type == nil || *req.Type == 0 {
		return nil, resultx.NewErrCode(resultx.FORUM_REACTION_TYPE_INVALID)
	}

	userId := jwt.GetUserId(l.ctx)
	if userId == 0 {
		return nil, resultx.NewErrCode(resultx.TOKEN_EXPIRE_ERROR)
	}

	postId := strconv.FormatUint(*req.EntryId, 10)
	postType := strconv.FormatInt(int64(globalkey.PostTypeKnowledgeBase), 10)
	reactionType := util.GetReactionType(*req.Type)
	var filters []string
	filters = append(filters, "PostId,equalTo:"+postId)
	filters = append(filters, "PostType,equalTo:"+postType)
	filters = append(filters, "UserId,equalTo:"+strconv.FormatUint(userId, 10))
	filters = append(filters, "Type,equalTo:"+reactionType)

	var preFilters []string
	preFilters = append(preFilters, "PostId,equalTo:"+postId)
	preFilters = append(preFilters, "PostType,equalTo:"+postType)
	preFilters = append(preFilters, "Type,equalTo:"+reactionType)

	res, err := l.svcCtx.BlogRpc.GetReactionLogList(l.ctx, &blogclient.BaseListReq{
		Preload:   pointy.GetPointer("blogReactionLog:PostId,Status,Count"),
		Filter:    pointy.GetPointer(strings.Join(filters, ";")),
		PreFilter: pointy.GetPointer(strings.Join(preFilters, ";")),
	})
	if err != nil {
		return nil, err
	}

	var status *uint32
	var count *uint64
	if len(res.List) > 0 {
		for _, v := range res.List {
			if v.Status != nil {
				status = v.Status
				break
			}
		}
	}
	if len(res.Extra) > 0 {
		for _, v := range res.Extra {
			if v.Count != nil {
				count = v.Count
				break
			}
		}
	}

	return &types.CheckEntryFavoriteResp{
		Done:  status,
		Count: count,
	}, nil
}
